#ifndef _SIPCLIENT2_H_
#define _SIPCLIENT2_H_

#include "SIPConstants.h"
#include "SIPRequest.h"
#include "SIPResponse.h"
#include "../Socket/Socket.h"

#include <queue>
#include <string>
using std::string;
using std::queue;

class CSipClient2
{
	private:
    bool m_bConnected;
		int m_iStatus;
		CSipRequest *m_sipLastSentRequest;
		CSipResponse *m_sipLastRecievedResponse;
		//
		bool m_bSipServerAddressChanged;
		//
		string m_strSipServerAddress;
		string m_strSipClientAddress;
		int m_iSipServerPort;
		int m_iSipClientPort;
		string m_strCalleeId;
                string m_strCalleeScreenName;
                string m_strCalleeServerAddress;
                string m_strUserId;
                string m_strScreenName;
		string m_strAuthUser;
		string m_strAuthPasswd;
                //
                string m_strFarRtpAddress;
                string m_strNearRtpAddress;
                int m_iFarRtpPort;
                int m_iNearRtpPort;
                int m_iRtpSessionId;
		//
		bool m_bInitialized;
		fd_set *m_fdsRead;
		fd_set *m_fdsWrite;
		CUdpServerSocket m_server;
		CUdpClientSocket m_client;
		//
		queue<CSipPacket *> m_qPacketQueue;

	protected:
		bool RecieveResponse();
		void SendRequestQueue();
                void PushLastRequest();
		//
		void PushSipPacket(CSipPacket *p);
		void PushRegister(int iCSeq, bool bAuthRequired = false);
		void PushInvite(int iCSeq, bool bProxyAuthRequired = false);
		void PushCancel(int iCSeq);
		void PushAck(int iCSeq);
		void PushBye(int iCSeq);
		void PushOk(int iCSeq);

	public:
		CSipClient2();
		~CSipClient2();
		//
                inline string GetFarRtpAddress() const { return m_strFarRtpAddress; }
                inline int GetFarRtpPort() const { return m_iFarRtpPort; }
                inline int GetStatus() const { return m_iStatus; }
		inline CSipPacket * GetLastSentRequest() const { return m_sipLastSentRequest; }
		inline CSipPacket * GetLastRecievedResponse() const { return m_sipLastRecievedResponse; }
		inline string GetSipServerAddress() const { return m_strSipServerAddress; }
		inline bool SipServerAdressChanged() const { return m_bSipServerAddressChanged; }
                //
                bool Connect(const string &strSipServerAddress, int iSipServerPort, int iSipClientPort);
                void Close();
                //
		bool Init(fd_set *fdsRead, fd_set *fdsWrite);
		bool SetFd();

    bool IsConnected();
                //
                int ProcessResponse();  // vraci SipStatus
                //
                void Register(const string &strUserId, const string &strSipClientAddress, const string &strScreenName,
                              const string &strAuthUser = "anonymous", const string &strAuthPasswd = "");
                void Invite(const string &strCalleeId, const string &strCalleeScreenName,
                            const string &strCalleeServerAddress, const string &strNearRtpAddress,
                            int iNearRtpPort, int iRtpSessionId);
                void Cancel();
		void Bye();
};

#endif	// _SIPCLIENT2_H_
